/**
 * @author Vladimir V. Voloshinov
 * Remote AMI call result holder 
 *
 */
package ru.isa.dcs.iarnet.util.poller;

/* AMI call result holder. Supports poller model */
public class CollocatedHolder	{

	boolean ready;
	Object value;
	Exception exception;

	public CollocatedHolder()	{
		ready = false;
		value = null;
		exception =null;
	}

	/**
	 * Non-blocking check of readiness.
	 * If true - get result (or exception) by getValue method 
	 *  
	 * @return Object as invoke operation does
	 * @throws SystemException or ResourceException as invoke does 
	 */
	public boolean isReady()	{return ready;}

	/**
	 * Synchronized getter of returned value.
	 * Will wait until result/exception will be known.
	 *  
	 * @return Object as invoke operation does
	 * @throws SystemException or ResourceException as invoke does 
	 */
	public synchronized Object getValue() throws Exception {
		if (!ready)	{
			try	{wait();}
			catch (InterruptedException ex)	{
				throw new RuntimeException("Unexpected interruption", ex);
			};
		}
		if (value == null)	{
			if (exception == null) // Return null as "nominal" result 
				return value;
			else	{ // Upcall exception that has been set
				throw exception;
//				if ( (exception instanceof RuntimeException) )
//					throw exception;
//				else
//					throw new RuntimeException("There wasn't RuntimeException:", exception);
			}
		}
		return value;
	}

	public synchronized void setException(Exception ex)	{
		exception = ex;
		ready = true;
		notify();
	};

	public synchronized void setValue(Object res)	{
		value = res;
		ready = true;
		notify();
	}

}